﻿using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Options;
using System.Diagnostics;
using System.IO;
using XYAC.Framework.WohuaMesExtend.IHI.Extensions;
using XYAC.Framework.WohuaMesExtend.IHI.LocalData.Models;

namespace XYAC.Framework.WohuaMesExtend.IHI.LocalData.Context
{
    public class LocalTomorrowDataContext : LocalDataContext
    {
        public LocalTomorrowDataContext(IOptionsMonitor<AppConfig> moduleConfig) : base(moduleConfig)
        {
            this.ConnectionString = moduleConfig.CurrentValue?.LocalDataConnectionString.Replace("{DateNow}", DateTime.Now.Date.AddDays(1).ToString("yyyy-MM-dd")); ;
        }
    }
    public class LocalYesterdayDataContext : LocalDataContext
    {
        public LocalYesterdayDataContext(IOptionsMonitor<AppConfig> moduleConfig) : base(moduleConfig)
        {
            this.ConnectionString = moduleConfig.CurrentValue?.LocalDataConnectionString.Replace("{DateNow}", DateTime.Now.Date.AddDays(-1).ToString("yyyy-MM-dd")); ;
        }
    }
    public class LocalDataContext : DbContext
    {
        public LocalDataContext(IOptionsMonitor<AppConfig> moduleConfig)
        {
            this.ConnectionString = moduleConfig.CurrentValue?.LocalDataConnectionString.Replace("{DateNow}", DateTime.Now.Date.ToString("yyyy-MM-dd"));
        }
        public DbSet<LocalRecord> LocalRecord { get; set; }
        public DbSet<SpecInfoSyncMapping> SpecInfoSyncMapping { get; set; }
        public DbSet<YB_LOT_INSPECT_Local> YB_LOT_INSPECT { get; set; }
        public string ConnectionString { get; protected set; }

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            //modelBuilder.HasDefaultSchema("");
            modelBuilder.Entity<SpecInfoSyncMapping>().ToTable("SpecInfoSyncMapping").HasKey(h => h.Guid);
            modelBuilder.Entity<LocalRecord>().ToTable("LocalRecord").HasKey(h => h.Guid);
            modelBuilder.Entity<YB_LOT_INSPECT_Local>().ToTable("YB_LOT_INSPECT").HasKey(h => h.LJ_ID);
            // 配置 TableInfo 为无键实体,用于查询表设计相关
            modelBuilder.Entity<TableInfo>().HasNoKey();
            base.OnModelCreating(modelBuilder);
            //this.Database.ExecuteSqlRaw("PRAGMA journal_mode=WAL;");
            base.OnModelCreating(modelBuilder);
        }
        // 使用可空类型来表示是否已经初始化
        private bool? _dbFileCreated = null;

        public bool GetDbFileCreated()
        {
            if (!_dbFileCreated.HasValue)
            {
                string connectionStr = Database.GetConnectionString();

                // 提取 Data Source 的值
                var dataSourceIndex = connectionStr.IndexOf("Data Source=", StringComparison.OrdinalIgnoreCase);
                if (dataSourceIndex < 0)
                {
                    throw new InvalidOperationException("连接字符串中未找到 'Data Source='。");
                }

                // 提取数据库文件路径部分（直到第一个分号或字符串结尾）
                int endIndex = connectionStr.IndexOf(";", dataSourceIndex);
                var dbFilePath = endIndex > dataSourceIndex
                    ? connectionStr.Substring(dataSourceIndex + "Data Source=".Length, endIndex - dataSourceIndex - "Data Source=".Length).Trim()
                    : connectionStr.Substring(dataSourceIndex + "Data Source=".Length).Trim();

                // 获取完整路径并检查文件是否存在
                var fullPath = Path.GetFullPath(dbFilePath);
                var directory = Path.GetDirectoryName(fullPath);
                if (!Directory.Exists(directory))
                {
                    Directory.CreateDirectory(directory);
                }
                _dbFileCreated = File.Exists(fullPath);
            }

            return _dbFileCreated.Value;
        }

        /// <summary>
        /// 当DB发生OnConfiguring用于配置数据库
        /// </summary>
        /// <param name="optionsBuilder"></param>
        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {

            // 配置 SQL Server 数据库连接字符串
#if DEBUG
            optionsBuilder.UseSqlite(ConnectionString);
            //optionsBuilder.UseSqlite(ConnectionString).LogTo(DB, LogLevel.Debug);
#endif

#if RELEASE
            optionsBuilder.UseSqlite(ConnectionString);
#endif
        }

        Action<string> DB => (string T) => { Debug.WriteLine(T); };
        public void TruncateLog()
        {
            //禁用磁盘WAL日志,并且将WAL日志提交到内存中执行,提高并发性能,另外减少磁盘开销,避免日志过大的问题
            this.Database.ExecuteSqlRaw("PRAGMA wal_checkpoint(TRUNCATE);");
        }
    }
}
